﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpMUD.Framework.Workflow.Generic;
using SharpMUD.Framework.Services.Configuration;

namespace SharpMUD.Application
{
    public partial class MudServerApplication
        : IControlledExecution, IHasExecutionStatus
    {
        #region IControlledExecution Members

        public void Start()
        {
            if (this.ExecutionStatus != ExecutionStatusTokens.Initialized)
                throw new InvalidExecutionStatusTransitionException(this.ExecutionStatus, ExecutionStatusTokens.Starting);
            this.ExecutionStatus = ExecutionStatusTokens.Starting;
            log.Info(this.ExecutionStatus.ToString());

            var servicesToStart =
                from s in this._LoadedServices
                where s is IControlledExecution
                orderby ServiceDependencyAttribute.GetEffectiveDependencies(s.GetType()).Count() ascending
                select s as IControlledExecution;

            foreach (var s in servicesToStart)
            {
                s.Start();
            }

            this.ExecutionStatus = ExecutionStatusTokens.Running;
            log.Info(this.ExecutionStatus.ToString());
        }

        public void Stop()
        {
            if (this.ExecutionStatus != ExecutionStatusTokens.Running)
                throw new InvalidExecutionStatusTransitionException(this.ExecutionStatus, ExecutionStatusTokens.Stopping);
            this.ExecutionStatus = ExecutionStatusTokens.Stopping;
            log.Info(this.ExecutionStatus.ToString());

            var servicesToStop =
                from s in this._LoadedServices
                where s is IControlledExecution
                orderby ServiceDependencyAttribute.GetEffectiveDependencies(s.GetType()).Count() ascending
                select s as IControlledExecution;

            foreach (var s in servicesToStop)
            {
                s.Stop();
            }

            this.ExecutionStatus = ExecutionStatusTokens.Stopped;
            log.Info(this.ExecutionStatus.ToString());
        }

        #endregion

        #region IHasExecutionStatus Members

        private IExecutionStatusToken _ExecutionStatus = ExecutionStatusTokens.UnInitialized;
        public IExecutionStatusToken ExecutionStatus
        {
            get
            {
                return _ExecutionStatus;
            }
            private set
            {
                if (_ExecutionStatus != value)
                {
                    var oldValue = _ExecutionStatus;
                    _ExecutionStatus = value;
                    if (ExecutionStatusChanged != null)
                        this.ExecutionStatusChanged(this, new SharpMUD.Framework.ValueChangedEventArgs<IExecutionStatusToken>(oldValue, value));
                }
            }
        }

        public event EventHandler<SharpMUD.Framework.ValueChangedEventArgs<IExecutionStatusToken>> ExecutionStatusChanged;

        #endregion
    }
}
